package com.bosssoft.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bosssoft.entity.dto.FibAccountDTO;
import com.bosssoft.entity.po.FibAccountPO;
import com.bosssoft.enums.CopyPropertityEnum;
import com.bosssoft.util.MD5Util;
import com.bosssoft.exception.DaoException;
import com.bosssoft.mapper.FibAccountMapper;
import com.bosssoft.page.PageResult;
import com.bosssoft.service.FibAccountService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

/**
 * 账户表(FibAccount)表服务实现类
 *
 * @author makejava
 * @since 2021-08-17 15:08:06
 */
@Slf4j
@Service("fibAccountService")
public class FibAccountServiceImpl extends ServiceImpl<FibAccountMapper, FibAccountPO> implements FibAccountService {
    @Resource
    private FibAccountMapper fibAccountMapper;

    /**
     * 通过账户Id转账操作
     *
     * @param fromId
     * @param toId
     * @param amount
     * @return
     */
    @Override
    @Transactional(rollbackFor = DaoException.class)
    public boolean transferById(Long fromId, Long toId, BigDecimal amount) {
        this.baseMapper.transferOutById(fromId, amount);
        this.baseMapper.transferInById(toId, amount);
        return true;
    }

    /**
     * 通过账户转账操作
     *
     * @param fromAcc
     * @param toAcc
     * @param amount
     * @return
     */
    @Override
    @Transactional(rollbackFor = DaoException.class)
    public boolean transferByAcc(Long fromAcc, Long toAcc, BigDecimal amount) {
        this.baseMapper.transferOutByAcc(fromAcc, amount);
        this.baseMapper.transferInByAcc(toAcc, amount);
        return true;
    }

    @Override
    public BigDecimal getBalanceByAcc(Long acc) {
        return this.baseMapper.getBalanceByAcc(acc);
    }

    @Override
    public BigDecimal getBalanceById(Long id) {
        return this.baseMapper.getBalanceById(id);
    }

    @Override
    public PageResult<FibAccountPO> page(Page<FibAccountPO> page, FibAccountPO fibAccountPO) {
        // 构造条件
        QueryWrapper<FibAccountPO> queryWrapper = new QueryWrapper<>();
        // 查询分页结果
        if (ObjectUtil.isNotNull(fibAccountPO.getAccId())) {
            queryWrapper.like("acc_id", fibAccountPO.getAccId());
        }
        if (ObjectUtil.isNotNull(fibAccountPO.getAccUsername())) {
            queryWrapper.like("acc_username", fibAccountPO.getAccId());
        }
        return new PageResult<>(this.page(page, queryWrapper));
    }

    @Override
    public FibAccountDTO selectOneById(Long id) {
        try {
            FibAccountPO fibAccountPO = this.fibAccountMapper.select(id);
            FibAccountDTO fibAccountDTO = new FibAccountDTO();
            BeanUtils.copyProperties(fibAccountPO, fibAccountDTO);
            return fibAccountDTO;
        } catch (Exception e) {
            throw DaoException.error(CopyPropertityEnum.RESOURCE_NULL_ERROR);
        }
    }

    @Override
    public List<FibAccountDTO> selectAll(Long page, Long limit) {
        try {
            Long offset = page * 10 - 10;
            if (limit == null) {
                limit = Long.valueOf(10);
            }
            List<FibAccountPO> fibAccountPOS = this.fibAccountMapper.selectAll(offset, limit);
            List<FibAccountDTO> fibAccountDTOS = new ArrayList<>();
            for (int i = 0; i < fibAccountPOS.size(); i++) {
                fibAccountDTOS.add(new FibAccountDTO());
                BeanUtils.copyProperties(fibAccountPOS.get(i), fibAccountDTOS.get(i));
            }
            return fibAccountDTOS;
        } catch (Exception e) {
            throw DaoException.error(CopyPropertityEnum.RESOURCE_NULL_ERROR);
        }
    }

    /**
     * 新增数据
     *
     * @param
     * @return 实例对象
     */
    @Override
    public boolean insert(FibAccountDTO fibAccountDTO) {
        try {
            FibAccountPO fibAccountPO = new FibAccountPO();
            fibAccountDTO.accPassword = MD5Util.getMD5(fibAccountDTO.getAccPassword());
            BeanUtils.copyProperties(fibAccountDTO, fibAccountPO);
            return this.fibAccountMapper.insert(fibAccountPO) > 0;
        } catch (Exception e) {
            throw DaoException.error(CopyPropertityEnum.RESOURCE_NULL_ERROR);
        }
    }

    @Override
    public boolean delete(Long accId) {
        FibAccountPO fibAccountPO = new FibAccountPO();
//        BeanUtils.copyProperties(fibAccountDTO, fibAccountPO);
        System.out.println(accId);
        return this.fibAccountMapper.delete(accId) > 0;
    }

    @Override
    public boolean update(FibAccountDTO fibAccountDTO) {
        FibAccountPO fibAccountPO = new FibAccountPO();
        fibAccountDTO.accPassword = MD5Util.getMD5(fibAccountDTO.getAccPassword());
        BeanUtils.copyProperties(fibAccountDTO, fibAccountPO);
        return this.fibAccountMapper.update(fibAccountPO);
    }

    @Override
    public boolean updateDeleted(FibAccountDTO fibAccountDTO) {
        FibAccountPO fibAccountPO = new FibAccountPO();
        BeanUtils.copyProperties(fibAccountDTO, fibAccountPO);
        return this.fibAccountMapper.updateDeleted(fibAccountPO);
    }

    @Override
    public boolean updatePassword(FibAccountDTO fibAccountDTO) {
        FibAccountPO fibAccountPO = new FibAccountPO();
        BeanUtils.copyProperties(fibAccountDTO, fibAccountPO);
        return this.fibAccountMapper.updatePassword(fibAccountPO);
    }

    @Override
    public boolean updateBalance(FibAccountDTO fibAccountDTO) {
        FibAccountPO fibAccountPO = new FibAccountPO();
        BeanUtils.copyProperties(fibAccountDTO, fibAccountPO);
        double accBalance;
        accBalance = this.fibAccountMapper.selectBalance(fibAccountPO);
        if (accBalance + fibAccountPO.getBalance() < 0) {
            return false;
        } else {
            return this.fibAccountMapper.updateBalance(fibAccountPO);
        }
    }

}
